package org.sucri.floxs.model;

import org.sucri.floxs.Tools;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User: Wen Yu
 * Date: Aug 9, 2007
 * Time: 11:47:39 PM
 * To change this template use File | Settings | File Templates.
 */
public class Invoker
{
  private Object   mObj    = null;
  private Method   mMethod = null;
  private Object[] mArgs   = null;

  public Invoker() { super(); }
  public Invoker(Object obj, Method m) { mObj = obj; mMethod = m; }

  public Object[] getArgs()           { return mArgs; }
  public void     setArgs(Object[] s) { mArgs = s; }

  public Object getData() { return mObj; }

  public Accesor getAccesor()
  {
    if (mMethod != null && mMethod.isAnnotationPresent(Accesor.class))
      return mMethod.getAnnotation(Accesor.class);

    return null;
  }
  
  public Object invoke(String arg)
      throws InvocationTargetException, IllegalAccessException
  {
    if (mMethod.getParameterTypes().length != 1)
      throw new RuntimeException("Numbers of Argument mismatch!");

    return invoke(newArgs(arg, mMethod.getParameterTypes()[0]));
  }
  public Object invoke(Object[] args)
      throws IllegalArgumentException, InvocationTargetException, IllegalAccessException
  {
    return mMethod.invoke(mObj, args);
  }
  protected Object[] newArgs(String arg, Class type)
  {
    if      (type == int.class || type == Integer.class)
      return new Object[] { Tools.isNull(arg) ? (Integer )null : new Integer(arg) };
    else if (type == long.class || type == Long.class)
      return new Object[] { Tools.isNull(arg) ? (Long )null : new Long(arg) };
    else if (type == float.class || type == Float.class)
      return new Object[] { Tools.isNull(arg) ? (Float )null : new Float(arg) };
    else if (type == double.class || type == Double.class)
      return new Object[] { Tools.isNull(arg) ? (Double )null : new Double(arg) };
    else if (type == List.class || type == Collection.class)
    {
      List<Object> args = new ArrayList<Object>();
      if (Tools.good(args))
      {
        String[] items = arg.split(",");
        for (String i : items) if (!Tools.isNull(i)) args.add(i);
      }
    }
    else if (type == Date.class)
      return new Object[] { Tools.isNull(arg) ? (Date )null : new Date(arg) };
    else if (type == java.sql.Date.class)
      return new Object[] { Tools.isNull(arg) ? (java.sql.Date )null : java.sql.Date.valueOf(arg) };
    else if (type == boolean.class || type == Boolean.class)
      return new Object[] { Tools.isNull(arg) ? (Boolean )null :
          arg.equalsIgnoreCase("f") || arg.equals("0") || arg.equalsIgnoreCase("false")};

    return new Object[] { arg };
  }
}
